package com.h3c.web.rest;

import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.h3c.dal.common.TableConstant;
import com.h3c.dal.dao.CasssoDeptDAO;
import com.h3c.dal.dao.CasssoOrganizationUnitDAO;
import com.h3c.dal.dao.CasssoRoleDAO;
import com.h3c.dal.dao.CasssoUserDAO;
import com.h3c.dal.dao.CasssoUserRoleRelationDAO;
import com.h3c.dal.entity.CasssoDeptDO;
import com.h3c.dal.entity.CasssoOrganizationUnitDO;
import com.h3c.dal.entity.CasssoRoleDO;
import com.h3c.dal.entity.CasssoUserDO;
import com.h3c.dal.entity.CasssoUserRoleRelationDO;
import com.h3c.dal.entity.query.CasssoDeptQuery;
import com.h3c.dal.entity.query.CasssoOrganizationUnitQuery;
import com.h3c.dal.entity.query.CasssoRoleQuery;
import com.h3c.dal.entity.query.CasssoUserQuery;
import com.h3c.web.common.BaseResponse;
import com.h3c.web.common.ErrorMsgEnum;
import com.h3c.web.common.constant.RoleConstant;
import com.h3c.web.common.constant.RoleConstant.RoleEnum;
import com.h3c.web.common.helper.UserHelper;
import com.h3c.web.common.utils.BeanUtil;
import com.h3c.web.common.utils.ListUtil;
import com.h3c.web.common.utils.MD5Util;
import com.h3c.web.common.utils.UUIDUtil;
import com.h3c.web.common.vo.CasssoOrganizationUnitVO;
import com.h3c.web.support.console.OrgSupport;

/**
 * @ClassName: OrgRest
 * @Description: 组织api
 * @author: d14287
 * @date: 2017年5月31日 下午3:46:06
 */
@Controller
@RequestMapping("console/org")
public class OrgRest {
	public static final Logger logger = LoggerFactory.getLogger(OrgRest.class);
	@Autowired
	private CasssoOrganizationUnitDAO casssoOrganizationUnitDAO;
	@Autowired
	private CasssoUserDAO casssoUserDAO;
	@Autowired
	private CasssoRoleDAO casssoRoleDAO;
	@Autowired
	private CasssoUserRoleRelationDAO casssoUserRoleRelationDAO;
	@Autowired
	private CasssoDeptDAO casssoDeptDAO;
	@Autowired
	private OrgSupport orgSupport;
	private Lock lock = new ReentrantLock();

	@RequestMapping(value = "/edit.ajax", method = RequestMethod.POST)
	public @ResponseBody
	BaseResponse update(HttpServletRequest request) throws Exception {
		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		List<FileItem> items = upload.parseRequest(request);
		CasssoOrganizationUnitDO ouDO = new CasssoOrganizationUnitDO();
		for (FileItem item : items) {
			if (item.isFormField()) {
				if ("formdata".equals(item.getFieldName())) {
					ouDO.setName(JSON.parseObject(item.getString("UTF-8"),
							CasssoOrganizationUnitDO.class).getName());
					ouDO.setOuId(JSON.parseObject(item.getString("UTF-8"),
							CasssoOrganizationUnitDO.class).getOuId());
				}
			}
			if (item.getName() != null && item.getName().startsWith("logo")) {
				byte[] logo = item.get();
				ouDO.setLogo(logo);
			} else if (item.getName() != null
					&& item.getName().startsWith("background")) {
				byte[] background = item.get();
				ouDO.setBackgroundPic(background);
			}
		}
		CasssoOrganizationUnitQuery query = new CasssoOrganizationUnitQuery();
		query.createCriteria().andOuIdEqualTo(ouDO.getOuId());
		ouDO.setOuId(null);
		casssoOrganizationUnitDAO.updateByExampleSelective(ouDO, query);
		return BaseResponse.trueOf();
	}

	@RequestMapping(value = "/editUnImg.ajax", method = RequestMethod.POST)
	public @ResponseBody
	BaseResponse updateUnImg(@RequestBody CasssoOrganizationUnitVO ouVO)
			throws Exception {
		CasssoOrganizationUnitDO ouDO = new CasssoOrganizationUnitDO();
		BeanUtil.copyProperties(ouVO, ouDO);
		CasssoOrganizationUnitQuery query = new CasssoOrganizationUnitQuery();
		query.createCriteria().andOuIdEqualTo(ouDO.getOuId());
		ouDO.setOuId(null);
		casssoOrganizationUnitDAO.updateByExampleSelective(ouDO, query);
		return BaseResponse.trueOf();
	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/delete.ajax", method = RequestMethod.GET)
	public @ResponseBody
	BaseResponse delete(@RequestParam("ouId") String ouId) throws Exception {
		CasssoDeptQuery deptQuery = new CasssoDeptQuery();
		deptQuery.createCriteria().andOutIdEqualTo(ouId)
				.andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
		List<CasssoDeptDO> deptList = casssoDeptDAO.selectByExample(deptQuery);
		if (ListUtil.isNotEmpty(deptList)) {
			return BaseResponse
					.falseOf(ErrorMsgEnum.org_cannot_delete.getMsg());
		}
		CasssoOrganizationUnitQuery orgQuery = new CasssoOrganizationUnitQuery();
		orgQuery.createCriteria().andOuIdEqualTo(ouId);
		CasssoOrganizationUnitDO record = new CasssoOrganizationUnitDO();
		record.setStatus(TableConstant.COMMON_STATUS_DELETE);
		casssoOrganizationUnitDAO.updateByExampleSelective(record, orgQuery);
		return BaseResponse.trueOf();
	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/query.ajax", method = RequestMethod.GET)
	public @ResponseBody
	BaseResponse query(@RequestParam("ouId") String ouId,
			HttpServletRequest request) throws Exception {
		CasssoOrganizationUnitQuery query = new CasssoOrganizationUnitQuery();
		query.createCriteria().andOuIdEqualTo(ouId)
				.andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
		List<CasssoOrganizationUnitDO> orgList = casssoOrganizationUnitDAO
				.selectByExample(query);
		if (ListUtil.isEmpty(orgList)) {
			BaseResponse.falseOf(ErrorMsgEnum.org_not_found.getMsg());
		}
		CasssoOrganizationUnitVO orgVO = new CasssoOrganizationUnitVO();
		BeanUtil.copyProperties(orgList.get(0), orgVO);
		return BaseResponse.trueOf(orgVO);
	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/queryAll.ajax", method = RequestMethod.GET)
	public @ResponseBody
	BaseResponse queryAll(HttpServletRequest request) throws Exception {
		Pair<CasssoOrganizationUnitQuery, CasssoOrganizationUnitQuery.Criteria> orgPair = orgSupport
				.generateOrgQuery(request);
		orgPair.getRight().andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
		List<CasssoOrganizationUnitDO> orgList = casssoOrganizationUnitDAO
				.selectByExample(orgPair.getLeft());
		return BaseResponse.trueOf(ListUtil.copyList(orgList,
				CasssoOrganizationUnitVO.class));
	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/fuzzyQuery.ajax", method = RequestMethod.GET)
	public @ResponseBody
	BaseResponse fuzzyQuery(@RequestParam("name") String name,
			HttpServletRequest request) throws Exception {
		Pair<CasssoOrganizationUnitQuery, CasssoOrganizationUnitQuery.Criteria> orgPair = orgSupport
				.generateOrgQuery(request);
		orgPair.getRight().andNameLike("%" + name + "%")
				.andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
		List<CasssoOrganizationUnitDO> list = casssoOrganizationUnitDAO
				.selectByExample(orgPair.getLeft());
		return BaseResponse.trueOf(list);
	}

	/**
	 * 添加组织： 用户 ->角色->用户角色关联->组织,因为图片两次提交，故采用串行化的隔离级别
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	@Transactional(isolation = Isolation.SERIALIZABLE)
	@RequestMapping(value = "/add.ajax", method = RequestMethod.POST)
	public @ResponseBody
	BaseResponse add(HttpServletRequest request) throws Exception {
		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		List<FileItem> items = upload.parseRequest(request);
		CasssoOrganizationUnitDO ouDO = null;
		for (FileItem item : items) {
			if (item.isFormField()) {
				if ("formdata".equals(item.getFieldName())) {
					ouDO = JSON.parseObject(item.getString("UTF-8"),
							CasssoOrganizationUnitDO.class);
					CasssoUserDO userDO = JSON.parseObject(
							item.getString("UTF-8"), CasssoUserDO.class);
					userDO.setPassword(MD5Util.encryption(userDO.getPassword()));
					// lock.lock();
					if (checkUserExist(userDO.getLoginId(), userDO)) {
						ouDO.setOuId(userDO.getOuId());
						break;
					}
					ouDO.setOuId(UUIDUtil.generateUUID());
					userDO.setUserId(UUIDUtil.generateUUID());
					userDO.setRegisterTime(new Date());
					userDO.setStatus(TableConstant.USER_STATUS_ACTIVATED);
					userDO.setOuId(ouDO.getOuId());
					casssoUserDAO.insert(userDO);
					CasssoRoleQuery roleQuery = new CasssoRoleQuery();
					roleQuery
							.createCriteria()
							.andRoleCodeEqualTo(RoleEnum.org_admin.getKey())
							.andStatusEqualTo(
									TableConstant.COMMON_STATUS_NORMAL);
					List<CasssoRoleDO> roleDOList = casssoRoleDAO
							.selectByExample(roleQuery);
					CasssoRoleDO roleDO = new CasssoRoleDO();
					if (ListUtil.isNotEmpty(roleDOList)) {
						roleDO = roleDOList.get(0);
					} else {
						roleDO.setRoleId(UUIDUtil.generateUUID());
						roleDO.setRoleCode(RoleConstant.RoleEnum.org_admin
								.getKey());
						roleDO.setRoleName(RoleConstant.RoleEnum.org_admin
								.getDesc());
						roleDO.setCreateBy(UserHelper.get());
						roleDO.setCreateTime(new Date());
						roleDO.setStatus(TableConstant.COMMON_STATUS_NORMAL);
						casssoRoleDAO.insert(roleDO);
					}
					CasssoUserRoleRelationDO userRoleDO = new CasssoUserRoleRelationDO();
					userRoleDO.setUrId(UUIDUtil.generateUUID());
					userRoleDO.setUserId(userDO.getUserId());
					userRoleDO.setRoleId(roleDO.getRoleId());
					userRoleDO.setStatus(TableConstant.COMMON_STATUS_NORMAL);
					casssoUserRoleRelationDAO.insert(userRoleDO);
					// lock.unlock();
				}
			}
		}
		for (FileItem item : items) {
			if (item.getName() != null && item.getName().startsWith("logo")) {
				byte[] logo = item.get();
				ouDO.setLogo(logo);
			} else if (item.getName() != null
					&& item.getName().startsWith("background")) {
				byte[] background = item.get();
				ouDO.setBackgroundPic(background);
			} else {
				continue;
			}
			// lock.lock();
			if (checkOrgExist(ouDO.getOuId())) {
				CasssoOrganizationUnitQuery query = new CasssoOrganizationUnitQuery();
				query.createCriteria().andOuIdEqualTo(ouDO.getOuId());
				ouDO.setOuId(null);
				casssoOrganizationUnitDAO.updateByExampleSelective(ouDO, query);
			} else {
				ouDO.setStatus(TableConstant.COMMON_STATUS_NORMAL);
				ouDO.setRegisteTime(new Date());
				casssoOrganizationUnitDAO.insert(ouDO);
			}
			// lock.unlock();
		}
		return BaseResponse.trueOf();
	}

	@SuppressWarnings({ "unchecked" })
	public boolean checkUserExist(String loginId, CasssoUserDO user)
			throws Exception {
		CasssoUserQuery query = new CasssoUserQuery();
		query.createCriteria().andLoginIdEqualTo(loginId);
		List<CasssoUserDO> userDOList = casssoUserDAO.selectByExample(query);
		if (ListUtil.isNotEmpty(userDOList)) {
			BeanUtil.copyProperties(userDOList.get(0), user);
			return true;
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	public boolean checkOrgExist(String ouId) throws Exception {
		CasssoOrganizationUnitQuery query = new CasssoOrganizationUnitQuery();
		query.createCriteria().andOuIdEqualTo(ouId)
				.andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
		List<CasssoOrganizationUnitDO> ouDOList = casssoOrganizationUnitDAO
				.selectByExample(query);
		if (ouDOList != null && !ouDOList.isEmpty()) {
			return true;
		}
		return false;
	}
}
